package com.tinusgraglin.enclusiv.datalayer.datasources

import com.squareup.moshi.JsonDataException
import com.tinusgraglin.enclusiv.datalayer.Exceptions
import com.tinusgraglin.enclusiv.datalayer.RemoteSourceCommunication
import okhttp3.MultipartBody
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
import java.io.File
import java.io.IOException

class PicsRemoteSource(private val communication: RemoteSourceCommunication) {
    private val serverUrl = communication.serverUrl
    private val client = communication.client

    fun upload(uid: Long, files: List<File>) : List<Long> {
        val byteArray: ByteArray
        val requestUrl = serverUrl.newBuilder()
            .addPathSegments("user_images/upload")
            .build()

        val requestBody = MultipartBody.Builder().apply {
            files.forEach {
                addFormDataPart("image", it.name, it.asRequestBody())
                addFormDataPart("id", uid.toString())
                addFormDataPart("type", it.extension)
            }
        }.build()

        val request = Request.Builder()
            .url(requestUrl)
            .post(requestBody)
            .build()

        val resp = client.newCall(request).execute()

        if (!resp.isSuccessful) {
            throw IOException("Request Error: ${resp.code}")
        } else {
            val pairResponse = communication.resultStrLongListResponseAdapter.fromJson(resp.body.string())
                ?: throw JsonDataException("Data conversion failed.")

            if (pairResponse.result != "success") {
                val pattern = "(0|([1-9][0-9]*)) files upload succeed, (0|([1-9][0-9]*)) files upload failed"
                val matchResult = Regex(pattern).matchEntire(pairResponse.result)
                if (matchResult != null && matchResult.groups.size == 2)  {
                    throw Exceptions.UploadFailure(matchResult.groups[0]!!.value.toUInt())
                } else {
                    throw IllegalStateException("Unexpected Result String")
                }
            } else {
                return pairResponse.data!!
            }
        }
    }

    fun getPic(iid: Long): ByteArray {
        val requestUrl = serverUrl.newBuilder()
            .addPathSegments("user_images/image")
            .addQueryParameter("id", iid.toString())
            .build()

        val responseBody = communication.templateGet(requestUrl)
        val data = responseBody.byteStream().readBytes()
        responseBody.byteStream().close()
        return data
    }
}